/**
 * 
 */
package org.ibase4j.web;

import java.text.SimpleDateFormat;
import java.util.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.toolkit.IdWorker;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.ibase4j.core.support.email.Email;
import org.ibase4j.core.util.EmailUtil;
import org.ibase4j.core.util.InstanceUtil;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.ibase4j.core.base.AbstractController;
import org.ibase4j.core.base.Parameter;
import org.ibase4j.core.support.Assert;
import org.ibase4j.core.support.HttpCode;
import org.ibase4j.core.util.SecurityUtil;
import org.ibase4j.core.util.UploadUtil;
import org.ibase4j.model.PlatProUser;
import org.ibase4j.provider.ISysProvider;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * 用户管理控制器
 * 
 * @author ShenHuaJie
 * @version 2016年5月20日 下午3:12:12
 */
@RestController
@Api(value = "用户管理", description = "用户管理")
@RequestMapping(value = "/user")
public class PlatProUserController extends AbstractController<ISysProvider> {
	public String getService() {
		return "platProUserService";
	}
	private static final byte[] KEY = { 9, -1, 0, 5, 39, 8, 6, 19 };
	@PostMapping("/read/edit")
	@ApiOperation(value = "修改用户信息")
	@RequiresPermissions("sys.base.user.update")
	public Object update(ModelMap modelMap, @RequestBody PlatProUser param) {
		Assert.isNotBlank(param.getAccount(), "ACCOUNT");
		Assert.length(param.getAccount(), 3, 15, "ACCOUNT");
		if (param.getId() != null) {
			if (param.getEnable() == null) {
				param.setEnable(1);
			}
			Parameter parameter = new Parameter(getService(), "queryById", param.getId());
			PlatProUser user = (PlatProUser) provider.execute(parameter).getResult();
			Assert.notNull(user, "USER", param.getId());
			if (StringUtils.isNotBlank(param.getPassword())) {
				if (!param.getPassword().equals(user.getPassword())) {
					param.setPassword(SecurityUtil.encryptPassword(param.getPassword()));
				}
			}
		} else if (StringUtils.isNotBlank(param.getPassword())) {
			param.setPassword(SecurityUtil.encryptPassword(param.getPassword()));
		}
		return super.update(modelMap, param);
	}

	// 查询用户
	@ApiOperation(value = "查询用户")
	@RequiresPermissions("sys.base.user.read")
	@PutMapping(value = "/read/list")
	public Object query(ModelMap modelMap, @RequestBody Map<String, Object> param) {
		return super.query(modelMap, param);
	}

	// 用户详细信息
	@ApiOperation(value = "用户详细信息")
	@RequiresPermissions("sys.base.user.read")
	@PutMapping(value = "/read/detail")
	public Object get(ModelMap modelMap, @RequestBody PlatProUser param) {
		return super.get(modelMap, param);
	}

	// 用户详细信息
	@ApiOperation(value = "删除用户")
	@RequiresPermissions("sys.base.user.delete")
	@DeleteMapping
	public Object delete(ModelMap modelMap, @RequestBody PlatProUser param) {
		return super.delete(modelMap, param);
	}

	// 当前用户
	@ApiOperation(value = "当前用户信息")
	@GetMapping(value = "/read/promission")
	public Object promission(ModelMap modelMap) {
		Long id = getCurrUser();
		Parameter parameter = new Parameter(getService(), "queryById", id);
		PlatProUser platProUser = (PlatProUser) provider.execute(parameter).getResult();
		modelMap.put("user", platProUser);
		parameter = new Parameter("platProAuthorizeService", "queryAuthorizeByUserId", id);
		logger.info("{} execute queryAuthorizeByUserId start...", parameter.getNo());
		List<?> menus = provider.execute(parameter).getResultList();
		logger.info("{} execute queryAuthorizeByUserId end.", parameter.getNo());
		modelMap.put("menus", menus);
		return setSuccessModelMap(modelMap);
	}

	// 当前用户
	@ApiOperation(value = "当前用户信息")
	@GetMapping(value = "/read/current")
	public Object current(ModelMap modelMap) {
		logger.info("进入方法获取当前用户信息--------------------------------------------");
		PlatProUser param = new PlatProUser();
		param.setId(getCurrUser());
		return super.get(modelMap, param);
	}

	@ApiOperation(value = "修改个人信息")
	@PostMapping(value = "/update/person")
	public Object updatePerson(ModelMap modelMap, @RequestBody PlatProUser param) {
		param.setId(getCurrUser());
		param.setPassword(null);
		Assert.isNotBlank(param.getAccount(), "ACCOUNT");
		Assert.length(param.getAccount(), 3, 15, "ACCOUNT");
		return super.update(modelMap, param);
	}
   @ApiOperation(value="重置密码")
   @RequestMapping(value ="/resetPassword",method = RequestMethod.POST)
   public Object resetPassword(HttpServletRequest request ,ModelMap modelMap,@RequestBody PlatProUser param){
	   param.setPassword(SecurityUtil.encryptPassword(param.getPassword()));
	   param.setUUID("");
	   Parameter parameter=new Parameter(getService(),"resetPassword",param);
	   provider.execute(parameter);
	   return setSuccessModelMap(modelMap);
   }

	/**
	 * 验证邮件重置密码链接有效性
	 * @param request
	 * @param modelMap
	 * @return
	 */
	@ApiOperation(value = "验证邮件重置密码链接有效性")
	@RequestMapping(value="/validateURL")
   public Object ValidateURL(HttpServletRequest request,ModelMap modelMap,@RequestBody PlatProUser param){
	   Parameter parameter=new Parameter(getService(),"validateURL",param);
	   logger.info("{}execute validateURL start...",parameter.getNo());
	   Integer count=(Integer) provider.execute(parameter).getResult();
	   logger.info("{}execute validateURL end...",parameter.getNo());

	   logger.info("param.account="+param.getAccount());
	   logger.info("param.UUID="+param.getUUID());

		if(count>=1){
			return setSuccessModelMap(modelMap);
		}else {return "";}
   }
	@ApiOperation(value = "修改用户头像")
	@PostMapping(value = "/update/avatar")
	public Object updateAvatar(HttpServletRequest request, ModelMap modelMap) {
		List<String> fileNames = UploadUtil.uploadImageData(request);
		if (fileNames.size() > 0) {
			PlatProUser param = new PlatProUser();
			param.setId(getCurrUser());
			for (int i = 0; i < fileNames.size(); i++) {
				String filePath = UploadUtil.getUploadDir(request) + fileNames.get(i);
				String avatar = UploadUtil.remove2DFS("platProUser", "U" + param.getId(), filePath).getRemotePath();
				param.setAvatar(avatar);
			}
			modelMap.put("data", param);
			return super.update(modelMap, param);
		} else {
			setModelMap(modelMap, HttpCode.BAD_REQUEST);
			modelMap.put("msg", "请选择要上传的文件！");
			return modelMap;
		}
	}

	// 修改密码
	@ApiOperation(value = "修改密码")
	@PostMapping(value = "/update/password")
	public Object updatePassword(ModelMap modelMap, @RequestBody PlatProUser param) {
		Assert.isNotBlank(param.getOldPassword(), "OLDPASSWORD");
		Assert.isNotBlank(param.getPassword(), "PASSWORD");
		Long userId = getCurrUser();
		String encryptPassword = SecurityUtil.encryptPassword(param.getOldPassword());
		Parameter parameter = new Parameter(getService(), "queryById", userId);
		logger.info("{} execute queryById start...", parameter.getNo());
		PlatProUser platProUser = (PlatProUser) provider.execute(parameter).getResult();
		logger.info("{} execute queryById end.", parameter.getNo());
		Assert.notNull(platProUser, "USER", param.getId());
		if (!platProUser.getPassword().equals(encryptPassword)) {
			throw new UnauthorizedException("原密码错误.");
		}
		platProUser.setPassword(SecurityUtil.encryptPassword(param.getPassword()));
		return super.update(modelMap, platProUser);
	}
	/**
	 * 发送重置密码的邮件
	 * @param request
	 * @param modelMap
	 * @return
	 */
	@ApiOperation(value = "忘记密码")
	@RequestMapping(value = "/forgetPwd")
	public Object forgetpassword(HttpServletRequest request, HttpServletResponse response, ModelMap modelMap,@RequestBody PlatProUser param) throws Exception{
		String emails=param.getEmail();
		String uuid=IdWorker.get32UUID();
		logger.info("通过email获取用户信息");
		Date time=new Date();
		logger.info("当前时间："+time);
		Parameter parameter = new Parameter(getService(),"isRegist",emails);
		PlatProUser result = (PlatProUser) provider.execute(parameter).getResult();
		JSONObject jsonobj=new JSONObject();
		if(result!=null){
			logger.info("通过email成功获取用户信息");
            if(compareTime(result.getSendTime(),time,result.getUUID())){
            	logger.info("重置密码链接失效或者uuid=null");
            	logger.info("Update uuid and time");
				result.setSendTime(time);
				result.setUUID(uuid);
			}else{
            	logger.info("重置密码在有效时间范围内，延长链接有效时间");
				result.setSendTime(time);
			}
			String account=result.getAccount();
			Email email=new Email();
			email.setHost("smtp.qq.com");
			email.setName("");//设置发送用户名
			email.setPassword("");//设置发送密码
			email.setSendTo(emails);
			email.setTopic("重置您的密码");
			email.setFrom("高新兆诚科技有限公司,1830955733@qq.com");//iBase4J,iBase4J@126.com
			/*email.setBody("您好"+emails+"<br/>"+"你已经请求了重置密码, 请复制下面的链接到浏览器上访问重置密码:<br/>" +
					"<a href=\"http://localhost/#/access/resetPassword?account=\'" + account+"\'\">复制右侧链接</a>"+"<br/>如果您没有请求重置密码请忽略这封邮件。");
			*/
			email.setBody("您好"+emails+"<br/>"+"你已经请求了重置密码, 请复制下面的链接到浏览器上访问重置密码,5分钟后链接失效:<br/>" +
					"<a href=\"http://localhost/#/access/cache/" + account+"/"+result.getUUID()+"\">http://localhost/#/access/cache/" + account + "/" + result.getUUID() + "</a><br/>如果您没有请求重置密码请忽略这封邮件。");
			Boolean bl=EmailUtil.sendEmail(email);
			/*Boolean bl=true;*/
			if(bl){
				logger.info("更新platpro_user_user表数据库uuid+sendTime ....start");
				parameter=new Parameter(getService(),"updateSendInfo",result);
				provider.execute(parameter);
				logger.info("更新platpro_user_user表数据库uuid+sendTime ....end");
				jsonobj.put("httpCode","200");
				jsonobj.put("msg","已经向"+emails+"邮箱发送重置密码邮件，请及时登录邮箱重置密码！");
			}else{
				logger.info("发送邮件出错！");
				jsonobj.put("httpCode","400");
				jsonobj.put("msg","向"+emails+"邮箱发送重置密码邮件失败！");
				}
		}else{
        	logger.info("不存在email对应的用户");
			jsonobj.put("httpCode","400");
			jsonobj.put("msg","您的邮箱"+emails+"没有在本系统注册过！");
		}
		return jsonobj.toJSONString();
	}
	/**
	 * 比较发送邮件时间和当前时间相差多少分钟，判断uuid是否为空
	 * @param t1
	 * @param t2
	 * @param uuid
	 * @return
	 */
	public boolean compareTime(Date t1,Date t2,String uuid){
		if(t1==null){return true;}
      long time1=t1.getTime();
      long time2=t2.getTime();
      long diff;
      long minute=0;
       try {
       	 if(time1<time2){
       	 	diff=time2-time1;
		 }else{
       	 	diff=time1-time2;
		 }
		 //days=diff/(1000*60*60*24);//计算天数
		   minute=diff/(1000*60);
	   }catch (Exception e){
		   logger.error("", e);
	   }finally {
		   if(minute>5||uuid.equals("")){
			   return true;
		   }else {return false;}
	   }
	}

}
